package com.mayblackcat.dy.utils;

import com.mayblackcat.dy.entity.Recommend;

import java.util.*;


/**
 * 协同推荐算法实现步骤：
 * 1.先建立一张用户和需要推荐物的评分系统表
 * 2.通过该表找出相邻用户id的k个用户，用于计算统计物品推荐度
 * 3.通过两两用户之间评分过的物品求相似度：
 *     方式一: 相似度=(两用户共同评过分的非推荐用户的物品总评分)/(需推荐用户物品总评分)
 *     方式二: 相似度=(相同喜欢物品数)/(两用户所有喜欢物品数)
 *     方式三(余弦相似度): 相似度=(将推荐用户物品评分*另一个用户对此物品评分)所有物品求和/(sqrt(推荐用户每个物品评分平方)*sqrt(另一个用户每个物品评分平方))
 * 4.求出推荐物品排行：取相似度前t高的用户,求出物品推荐度：物品推荐度=(相似度*该用户对该物品评分值+...)/(用户相似度1+相似度2+...)
 * 5.放入一个集合中按推荐度，向此用户推荐。
 *
 *
 *
 *
 * @author ASUS
 */




public class CoreRecommend {


        public List<Integer> recommend(Integer userId, List<Recommend> list) {

            //可以通过用户id随机10-20位作为相邻用户进行匹配。
            //通过循环遍历取出每位用户视频id号和对应评分通过map去存储
            //需要通过list集合存储需要推荐视频用户的所有看过视频id号
            //需要通过list集合存储需要推荐视频用户的所有没看过视频id号


            return null;
        }



        /**
         * 两用户之间相似度
         * @Param   userScore1需要推荐视频的用户
         * @Param   watchedVideo 已看过视频id号
         * @author MayBlackCat
         * @return
         */
        private double twoSimilarity(Map<Long,Long> userScore1,Map<Long,Long> userScore2,List<Long> watchedVideo){
            //保存每两个用户间对同一个物品评分乘积

            double sumScore=0;
            double sumUser1=0;
            double sumUser2=0;
            for (int i = 0; i < userScore1.size() ; i++) {
                //找出两用户看过的视频计算余弦相似度
                if(userScore2.get(watchedVideo.get(i))!=null){
                    sumScore+=userScore1.get(watchedVideo.get(i))*userScore2.get(watchedVideo.get(i));
                    sumUser1+=userScore1.get(watchedVideo.get(i))*userScore1.get(watchedVideo.get(i));
                    sumUser2+=userScore2.get(watchedVideo.get(i))*userScore2.get(watchedVideo.get(i));
                }

            }
            //得出两用户相似度
            return sumScore/(Math.sqrt(sumUser1)*Math.sqrt(sumUser2));
        }

        /**
         * 某个视频对该用户推荐度
         * @Param   userScore 需要推荐用视频户没看过的某个视频其他用户对其评分
         * @author MayBlackCat
         * @return
         */
        private double VideoRecommendation(double[] similarity,double[] userScore){

            double sumSimilarity=0;
            double sum=0;
            for (int i = 0; i < similarity.length; i++) {
                sum+=similarity[i]*userScore[i];
                sumSimilarity+=similarity[i];
            }
            //得出该物品推荐度
            return sum/sumSimilarity;
        }




}
